﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chapter19
{
    partial class Program
    {
        private delegate void Feedback(int value);

        internal static void Begin(Action action, bool active = false)
        {
            if (active)
            {
                Console.WriteLine("开始演示：");
                action();
                Console.WriteLine("演示完毕：");
                Console.ReadLine();
            }
        }

        internal static void C01()
        {
            int? x = 5;
            int? y = null;
            Console.WriteLine("x: HasValue={0}, Value={1}", x.HasValue, y.Value);
            Console.WriteLine("y: HasValue={0}, Value={1}", x.HasValue, y.Value);
            Point? p1 = new Point(1, 1);
            Point? p2 = new Point(2, 2);
            Console.WriteLine("Are points equal? " + (p1 == p2).ToString());
            Console.WriteLine("Are points not equal? " + (p1 != p2).ToString());
        }

        private static void ConversionsAndCasting()
        {
            int? a = 5;
            int? b = null;
            int c = (int)a;
            double? d = 5;
            Console.WriteLine(d);
            double? e = b;
        }

        private static void Operators()
        {
            int? a = 5;
            int? b = null;
            a++;
            b = -b;
            a = a + 3;
            b = b + 3;
            if (a == null)
                Console.WriteLine("no");
            else
                Console.WriteLine("yes");
            if (b == null)
                Console.WriteLine("yes");
            else
                Console.WriteLine("no");
            if (a != b)
                Console.WriteLine("yes");
            else
                Console.WriteLine("no");
            if (a < b)
                Console.WriteLine("no");
            else
                Console.WriteLine("yes");
        }

        private static int? NullableCodeSize(int? a, int? b)
        {
            return (a + b);
        }

        private struct Point
        {
            private int x, y;

            public Point(int x, int y)
            {
                this.x = x;
                this.y = y;
            }

            public static bool operator ==(Point p1, Point p2)
            {
                return p1.x == p2.x && p1.y == p2.y;
            }

            public static bool operator !=(Point p1, Point p2)
            {
                return !(p1 == p2);
            }

            public override bool Equals(object obj)
            {
                return this.Equals((Point)obj);
            }

            public override int GetHashCode()
            {
                return x ^ y;
            }
        }

        private static void NullCoalescingOperator()
        {
            int? b = null;
            int x = b ?? 123;
            Console.WriteLine(x);
            string filename = GetFilename() ?? "Untitled";
            Console.WriteLine(filename);
            Func<string> f = () => SomeMethod() ?? "Untitled";
            string s = SomeMethod() ?? SomeMethod() ?? "Untitled";
            Console.WriteLine("{0} {1}", f, s);
        }

        private static string GetFilename()
        {
            return null;
        }

        private static string SomeMethod()
        {
            return null;
        }

        private static void C02()
        {
            {
                int? n = null;
                object o = n;
                Console.WriteLine("o is null={0}", o == null);
                n = 5;
                o = n;
                Console.WriteLine("o's type={0}", o.GetType());
            }
            {
                object o = 5;
                int? a = (int)o;
                int b = (int)o;
                o = null;
                try
                {
                    a = (int)o;
                    b = (int)o;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
            {
                int? x = 5;
                Console.WriteLine(x.GetType());
            }
            {
                int? n = 5;
                int result = ((IComparable)n).CompareTo(5);
                Console.WriteLine(result);
            }
        }
    }
}
